using System.Collections.Generic;
using AIFSContentManagementSystem;
using AIFSContentManagementSystem.Articles;
using AIFSContentManagementSystem.Criteria;


namespace AIFSCMS.Infrastructure.ProxyModels
{
    /// <summary>
    /// Article Proxy is used to lazy load overridable properties
    /// </summary>
    public class ArticleProxy : Article, IProxy
    {
        IRepositoryMap repositoryMap;

        public IRepositoryMap RepositoryMap
        {
            get { return repositoryMap; }
            set { repositoryMap = value; }
        }

        public ArticleProxy()
        {
        }

        #region Lazy loading
        
        bool areCriteriaLoaded;        
        object criteriaLoadLock = new object();

        public override List<Criterion> Criteria
        {            
            get
            {
                if (!areCriteriaLoaded)
                {
                    lock (criteriaLoadLock)
                    {
                        if (!areCriteriaLoaded)
                        {
                            IArticleRepository articleRepository = this.RepositoryMap.Get<IArticleRepository>();
                            ICriteriaRepository criteriaRepository = this.RepositoryMap.Get<ICriteriaRepository>();

                            List<ArticleCriterion> articleCriteria = articleRepository.GetArticleCriteria(this);
                            if (articleCriteria == null)
                                articleCriteria = new List<ArticleCriterion>();

                            foreach (ArticleCriterion articleCriterion in articleCriteria)
                            {
                                Criterion criterion = criteriaRepository.GetCriterion(articleCriterion.CriteriaId);
                                if (criterion != null)
                                    base.Criteria.Add(criterion);
                            }

                            areCriteriaLoaded = true;
                        }
                    }
                }

                return base.Criteria;
            }
            set
            {
                base.Criteria = value;
            }
        }

        bool areFragmentsLoaded;
        object fragmentsLoadLock = new object();

        public override List<Fragment> Fragments
        {
            get
            {
                if (!areFragmentsLoaded)
                {
                    lock (fragmentsLoadLock)
                    {
                        if (!areFragmentsLoaded)
                        {
                            IArticleRepository articleRepository = this.RepositoryMap.Get<IArticleRepository>();
                            
                            List<ArticleFragment> articleFragments = articleRepository.GetArticleFragments(this);
                            if (articleFragments == null)
                                articleFragments = new List<ArticleFragment>();

                            foreach (ArticleFragment articleFragment in articleFragments)
                            {
                                Fragment fragment = articleRepository.GetFragment(articleFragment.FragmentId);
                                base.Fragments.Add(fragment);
                            }

                            areFragmentsLoaded = true;
                        }
                    }
                }

                return base.Fragments;
            }
            set
            {
                base.Fragments = value;
            }
        }        
        #endregion

        #region IProxy Members

        public void EagerLoad()
        {
            //Force invoke the lazy loading            
            List<Criterion> criteria = this.Criteria;
            List<Fragment> fragments = this.Fragments;
        }

        #endregion
    }
}
